问题
刚才碰到了一个这样的问题:有一个由对象组成的数组,把其中一个对象赋值给变量p
,然后改变了p
的属性,对应的原来数组中的对象的属性也会随之改变。
var arr = [{x:0, y:0}, {x:0, y:0}]
var p = arr[0]
p.x = 1
p.y = 2
console.log(arr) // [{x:1, y:2}, {x:0, y:0}]
探究
我一开始以为这是数组的什么神奇特性,经过几番试验发现只有由对象组成的数组有这个问题,隐隐觉得这是对象的某个特性,然后又试了下,果然如此!
var a = {x:0, y:0}
var p = a
p.x = 1
console.log(a) // {x:1, y:0}
把a
赋值给变量p
之后,改变p
的某个属性,a
中对应的属性也会随之改变。
原因
简单地想了一下原因,不知道正确不正确:var p = a
是让p
指向了a
所代表的对象。同理,var a = {x:0, y:0}
是让a
指向了{x:0, y:0}
这样一个对象。所以实际上p
和a
指向的是同一个对象,修改其它们中任何一个都会使另一个一同改变。
解决办法
那有没有让p
改变之后a
保持不变的办法呢?
有的!
var a = {x:0, y:0}
var p = {}
p.x = a.x
p.y = a.y
通过这种方式把a
的属性一一对应地赋值给p
,之后对p
做出的任何修改都不会影响到a
。但是这种方法很麻烦,特别是碰到属性很多的对象,那么可以写个函数来完成这个工作:
function cloneObj(obj) {
var newObj = {}
for(var prop in obj) {
newObj[prop] = obj[prop]
}
return newObj
}
var a = {x:0}
var p = cloneObj(a)
p.x = 2
console.log(p) // {x:2}
console.log(a) // {x:0}
成功了!修改p
的属性之后a
的属性没有随之改变。
后来网上查了查,发现js中有深拷贝和浅拷贝这样的区分,粗粗看了一遍。但是没有更多的实际使用经验所以理解也不是很深刻,如果以后有了更深的见解的话到时候再来写一篇。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。